-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Remove ldap caching and move to the Zitadel v2 API #79
base: main
Are you sure you want to change the base?
Conversation
For UKE we'll need to make sure to test this with a dry run |
user.set_idp_links(vec![IdpLink::new() | ||
.with_user_id(imported_user.external_user_id.to_string()) | ||
.with_idp_id(self.zitadel_config.idp_id.clone()) | ||
// TODO: Figure out if this is the correct value; empty is not permitted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be confirmed to work before we merge; we have no way to test if IDP logins actually work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I ended up reading the source code to figure out how Zitadel handles IDP IDs, I also figured out what the "name" means. I originally just wrote this comment:
This refers to the "username" that the search filter defined in the IDP config resolves to. This means that for our IDP links to work, that needs to be configured to resolve to the user's email address. See: https://github.com/zitadel/zitadel/blob/250f2344c8c2292ca9b861cdd12223d0b4719d43/internal/idp/providers/ldap/session.go#L230
That should make it into the readme, though.
The UKE source should be unaffected, because it doesn't need to parse external IDs from Zitadel. But yeah, probably prudent to do dry runs for the first sync after updating in general, this is a pretty big change. |
20a194f
to
35148f4
Compare
Remaining before this can be merged:
|
There is a clash between CSV and LDAP at this point. When we import CSV, it wrongly deletes Zitadel users not present in the CSV (or rather users that it couldn't match). |
Ideal behavior would of course be that switching between LDAP/CSV is possible, but this is not a use case we actually currently have, so while not ideal, it's probbaly fine for this to happen.
Yes, this is already a planned feature, see #75. We should do that as a separate task, though, as mixing the sources will for now be unsupported. We should probably make sure with product that this is indeed fine, however. |
Okay, in that case, we can merge the updated tests from: #80 |
Codecov ReportAttention: Patch coverage is
✅ All tests successful. No failed tests found.
Additional details and impacted files@@ Coverage Diff @@
## main #79 +/- ##
==========================================
+ Coverage 86.76% 91.38% +4.62%
==========================================
Files 7 8 +1
Lines 1352 1277 -75
==========================================
- Hits 1173 1167 -6
+ Misses 179 110 -69
Continue to review full report in Codecov by Sentry.
|
edd027e
to
6f6db25
Compare
When we merge this we should tag a new version and notify Niklas |
6f6db25
to
da89731
Compare
This allows using the debug impls of our User structs without worrying too much about accidentally exposing PII. Note that this means `external_user_id` should *never* contain PII, and as such we'll have to change the CSV source. An issue about this will be opened separately.
src/user.rs
Outdated
/// See | ||
/// https://www.notion.so/famedly/Famedly-UUID-Specification-adc576f0f2d449bba2f6f13b2611738f | ||
pub fn famedly_uuid(&self) -> String { | ||
Uuid::new_v5(&FAMEDLY_NAMESPACE, self.external_user_id.as_bytes()).to_string() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is no longer correct. We need to encode the raw byte value in the UUID, not the hex-encoded string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should write tests that explicitly confirm this, so we don't accidentally change it again.
src/zitadel.rs
Outdated
}; | ||
if self.feature_flags.is_enabled(FeatureFlag::SsoLogin) { | ||
user.set_idp_links(vec![IdpLink::new() | ||
.with_user_id(imported_user.external_user_id.clone()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to use the broken base64-encoded scheme here for Zitadel to interpret the IDs "correctly".
We should probably also send an issue upstream about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need a test to confirm this is correctly encoding IDs too.
3b8816b
to
15dca27
Compare
|
||
let user = zitadel.get_user_by_login_name("delete_me@famedly.de").await; | ||
assert!(user.is_err_and(|error| matches!(error, ZitadelError::TonicResponseError(status) if status.code() == TonicErrorCode::NotFound))); | ||
} | ||
|
||
// Currently fails because CSV uses non-hex encoded IDs, need to think | ||
// about how to fit this into the overall workflow | ||
#[ignore] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not working yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose the CSV backend should simply also hex-encode any IDs, and we simply make this an assumption of all sources so that we can rely on this being correct all the time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, all IDs should go through the encoding
15dca27
to
3ebe290
Compare
@@ -1,17 +1,17 @@ | |||
#![cfg(test)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add one more test, to assert that SSO linking actually works. I believe Zitadel is set up to allow this already, we just need to add a test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added a new test test_e2e_sso_linking
. Is that what you meant? Feel free to tweak it.
@@ -1,17 +1,17 @@ | |||
#![cfg(test)] | |||
#![allow(clippy::expect_fun_call)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should add this to the clippy config, and add it to our company-wide clippy config, if we don't like that lint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to create an issue out of this and leave it explicitly in the test file for this PR.
18842a2
to
65d5928
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of things I noticed, meaning as points of discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good for manual tests now.
Closes: #24
Closes: #53
Closes: #30
WIP because there are some things to clear up still. The tests will all fail here, but with some fudging of the sources almost all tests pass.
There are a few things that need to be discussed/covered:
Multi-source config/test suite
Previously, we wanted to support specifying multiple sources simultaneously, since that came somewhat for free. With the removal of the cache, however, only the UKT source uses email addresses to identify users, and in fact only it has a concept of "removed" users, which means that it fundamentally needs to be handled separately from the other sources. Trying to support multi-source definitions is much more tricky with this limitation, so I believe we should not do so.
This is the cause of most of the remaining failures; the test suite was written around the assumption that we can just dump all kinds of sources into one big config file, and for getting this over the line I've ignored also rewriting the test suite so far, instead testing by only having the respective source actively usable in code for the time being.
External user ID encoding
Since we universally use the external user IDs to uniquely identify users now, and we actually pull data from Zitadel instead of just pushing, we now need to re-ingest the user IDs we've written to the nickname field. Unfortunately, because of ldap3's odd behavior of silently converting byte-typed values to strings when they can be, but otherwise returning bytes, we need to base64-encode these IDs.
So far we've just encoded any values that were bytes, and left strings alone - alas, apparently you can end up with strings randomly being valid base64 values (e.g.
starttls
). This means that we do not have a way to distinguish between IDs that were encoded and IDs that were not - when we get unlucky, this can make it impossible to uniquely identify a user, since decoding stringly-typed IDs can sometimes result in valid values.Fixing this in the current implementation is easy (simply prefix encoded strings with a prefix, or encode all values, since UTF-8 strings are also valid byte strings), but backwards compatibility is a problem, since users with encoded IDs already exist in production.
It's possible that there is no way around runs in which some users will be deleted and immediately re-created.
Zitadel version
Due to the various recent Zitadel bugs, we need to update the Zitadel version in this PR. I've currently gone with the latest (
2.64.1
), but maybe we want another version?Remaining tasks: